﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using DatabaseCore;
using System.Windows.Threading;
using System.Windows;
using System.Transactions;

namespace Export.Ui.ViewModel
{
    using DatabaseCore;
    using SystemCore;
    using FirstFloor.ModernUI.Presentation;
    using GalaSoft.MvvmLight;
    using FirstFloor.ModernUI.Windows.Controls;
    using System.Globalization;
    using System.Windows.Controls;
    using System.Diagnostics;
    using System.Data;
    using System.Reflection;
    using System.ComponentModel;

    public class OrderAllViewModel : ViewModelBase
    {
        private const string C_SHEET_NAME = "Check";
        private const string C_KEY_ORDER = "Order";

        private ObservableCollection<tbl_Order> _orders = new ObservableCollection<tbl_Order>();
        private OrderDao orderProvider = new OrderDao();
        private OrderDetailDao orderDetailProvider = new OrderDetailDao();
        private ProdQueueDao prodQueueProvider = new ProdQueueDao();
        private ProductQueueMappedDao productQueueMappedProvider = new ProductQueueMappedDao();
        private ExcelDao excelProvider = new ExcelDao();
        private GenerateNoDao generateNoProvider = new GenerateNoDao();
        private ProductSummaryDao productSummaryProvider = new ProductSummaryDao();
        //private SapDao sapProvider = new SapDao();

        private bool _autoRefresh = false;
        private int _status;
        

        public OrderAllViewModel(int status)
        {
            _status = status;
            InitialData(this, null);
            if (_autoRefresh)
            {
                DispatcherTimer dispatcherTimer = new DispatcherTimer();
                dispatcherTimer.Tick += new EventHandler(InitialData);
                dispatcherTimer.Interval = new TimeSpan(0, 0, 30);
                dispatcherTimer.Start();
            }

            InitialCommand();
        }


        public tbl_Order SelectedItem { get; set; }

        public RelayCommand MouseDoubleClickCommand { get; private set; }

        public RelayCommand UploadOrderCommand { get; private set; }

        public RelayCommand ExportExcelCommand { get; private set; }

        public ObservableCollection<tbl_Order> Orders
        {
            get
            {
                return _orders;
            }
            set
            {
                _orders = value;
            }
        }

        public ModernDialog dialog { get; set; }

        private void ShowOrderDetails(object parameter)
        {
            if (parameter == null)
            {
                return;
            }

            tbl_Order selected = (tbl_Order)parameter;
            dialog = new ModernDialog
            {
                Title = "Details of order " + selected.OrderNo,
                Content = new Pages.OrderDetail(selected.OrderNo, this),
               // SizeToContent = System.Windows.SizeToContent.Manual,
                MinWidth = 1000,
                MinHeight = 500
            };
            Button hidden = new ModernButton();
            hidden.Visibility = System.Windows.Visibility.Hidden;
            dialog.Buttons = new Button[] { hidden };
            dialog.ShowDialog();
            RefreshGrid();
        }

        private void InitialData(object sender, EventArgs e)
        {
            RefreshGrid();
        }

        private void RefreshGrid()
        {
            _orders.Clear();
            var orders = orderProvider.Search(null, _status);
            foreach (var order in orders)
            {
                order.StatusName = EnumHelpers.GetDescription((EOrderStatus)order.Status);
                _orders.Add(order);
            }
        }

        private void InitialCommand()
        {
            MouseDoubleClickCommand = new RelayCommand(ShowOrderDetails);
            UploadOrderCommand = new RelayCommand(UploadOrder);
            ExportExcelCommand = new RelayCommand(ExportToExcel);
        }

        private void UploadOrder(object parameter)
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();

            // Set filter for file extension and default file extension 
            dlg.DefaultExt = ".txt";
            dlg.Filter = "EXCEL Files (*.xls)|*.xlsx";


            // Display OpenFileDialog by calling ShowDialog method 
            Nullable<bool> result = dlg.ShowDialog();
            if (result == true)
            {
                // Upload Document
                using (var ts = new TransactionScope())
                {
                    string filename = dlg.FileName;

                   // UploadExcel(filename);

                    ts.Complete();
                }
            }
        }

        //private void UploadExcel(string fileName)
        //{
        //    Excel.Application xlApp = null;
        //    Excel.Workbook xlWorkBook = null;
        //    Excel.Worksheet xlWorkSheet = null;
        //    Excel.Range xlRange = null;

        //    try
        //    {
        //        xlApp = new Excel.Application();
        //        xlWorkBook = xlApp.Workbooks.Open(fileName);
        //        xlWorkSheet = xlWorkBook.Sheets[C_SHEET_NAME];
        //        xlRange = xlWorkSheet.get_Range("A1", "Z500");  //500 x 26

        //        //This load data into memory, it's faster
        //        object[,] values = (object[,])xlRange.Value2;

        //        tbl_Order order = new tbl_Order();
        //        MappingOrderData(values, order);
        //        List<tbl_OrderDetail> orderDetail = new List<tbl_OrderDetail>(); ;
        //        MappingOrderDetailData(values, order, orderDetail);

        //        orderProvider.Insert(order);
        //        orderDetailProvider.Insert(orderDetail);

        //        tbl_ExcelFile excel = null;
        //        MappingExcelData(fileName, out excel);
        //        excelProvider.Insert(excel);

        //        MessageBox.Show("Upload successful.");
        //    }
        //    catch (Exception ex)
        //    {
        //        MessageBox.Show(ex.Message);
        //    }
        //    finally
        //    {
        //        xlWorkBook.Close(false, null, null);
        //        xlApp.Quit();

        //        releaseObject(xlWorkSheet);
        //        releaseObject(xlWorkBook);
        //        releaseObject(xlApp);
        //        RefreshGrid();
        //    }
        //}


        #region Mapping Data

        private void MappingExcelData(string fileName, out tbl_ExcelFile excel)
        {
            excel = new tbl_ExcelFile();
            excel.PathName = fileName;

            excel.CreateBy = UserContext.FullName;
            excel.CreateDate = DateTime.Now;
        }

        private void MappingOrderData(object[,] values, tbl_Order order)
        {
            //order = new tbl_Order();

            order.OrderNo = GenerateOrderNo();
            order.RefOrderNo = values[5, (int)EExcelCol.C].ToString().Trim();
            order.OrderDate = DateTime.FromOADate(Convert.ToDouble(values[5, (int)EExcelCol.E]));
            order.InvoiceNo = values[5, (int)EExcelCol.J].ToString().Trim();
            order.PortOfShipment = values[6, (int)EExcelCol.C].ToString().Trim();
            order.PortOfDestination = values[6, (int)EExcelCol.H].ToString().Trim();
            //order.BuyerCode = xlRange.Cells["", ""].Value2.ToString().Trim();
            //order.BuyerName = xlRange.Cells["", ""].Value2.ToString().Trim();
            //order.ShipmentNote = xlRange.Cells["", ""].Value2.ToString().Trim();
            //order.ConsigneeName = xlRange.Cells["", ""].Value2.ToString().Trim();
            order.Payment = values[11, (int)EExcelCol.J].ToString().Trim();
            //order.PONo = xlRange.Cells["", ""].Value2.ToString().Trim();
            //order.Location = xlRange.Cells["", ""].Value2.ToString().Trim();

            //อ่านผลรวมที่ detail
            //order.TotalQty = Convert.ToInt32(xlRange.Cells[24, "K"].Value2);
            //order.TotalPackage = Convert.ToInt32(xlRange.Cells[25, "K"].Value2);
            //order.TotalAmount = Convert.ToDecimal(xlRange.Cells[26, "K"].Value2);
            //order.TotalWeight = Convert.ToDecimal(xlRange.Cells[27, "K"].Value2);

            order.Status = (int)EOrderStatus.Order;

            order.CreateBy = UserContext.FullName;
            order.CreateDate = DateTime.Now;
            order.UpdateBy = UserContext.FullName;
            order.UpdateDate = DateTime.Now;
        }

        private void MappingOrderDetailData(object[,] values, tbl_Order order, List<tbl_OrderDetail> orderDetailList)
        {
            string orderNo = order.OrderNo;
            int record = 14;
            while (values[record, (int)EExcelCol.A] != null)
            {
                string productCode = values[record, (int)EExcelCol.D].ToString().Trim();

                tbl_OrderDetail orderDetail = new tbl_OrderDetail();

                orderDetail.OrderNo = orderNo;
                orderDetail.ItemNo = Convert.ToInt32(values[record, (int)EExcelCol.A]);
                orderDetail.ItemId = values[record, (int)EExcelCol.B].ToString().Trim();
                //orderDetail.ItemName;
                orderDetail.ProductId = productCode;
                //orderDetail.ProductName;
                orderDetail.Qty = Convert.ToInt32(values[record, (int)EExcelCol.E].ToString());
                orderDetail.ReceivedQty = 0;
                orderDetail.RemainingQty = Convert.ToInt32(values[record, (int)EExcelCol.E].ToString());
                orderDetail.UnitPrice = Convert.ToDecimal(values[record, (int)EExcelCol.F].ToString());
                orderDetail.Amount = Convert.ToDecimal(values[record, (int)EExcelCol.G].ToString());
                orderDetail.PcsPerBox = Convert.ToInt32(values[record, (int)EExcelCol.H].ToString());
                orderDetail.Package = Convert.ToInt32(values[record, (int)EExcelCol.I].ToString());
                orderDetail.WeightPerUnit = Convert.ToDecimal(values[record, (int)EExcelCol.J].ToString());
                orderDetail.Weight = Convert.ToDecimal(values[record, (int)EExcelCol.K].ToString());
                orderDetail.MaterialNo = values[record, (int)EExcelCol.L].ToString().Trim(); //sapDao.GetMaterialNo(productCode);
                //orderDetail.Plant = values[record, "N"].Value2.ToString().Trim(); //GetFromSAP();

                orderDetail.CreateBy = UserContext.FullName;
                orderDetail.CreateDate = DateTime.Now;
                orderDetail.UpdateBy = UserContext.FullName;
                orderDetail.UpdateDate = DateTime.Now;

                orderDetailList.Add(orderDetail);
                record++;
            }

            //Get header total
            order.TotalQty = Convert.ToInt32(values[record, (int)EExcelCol.K]);
            order.TotalPackage = Convert.ToInt32(values[record + 1, (int)EExcelCol.K]);
            order.TotalAmount = Convert.ToDecimal(values[record + 2, (int)EExcelCol.K]);
            order.TotalWeight = Convert.ToDecimal(values[record + 3, (int)EExcelCol.K]);
        }

        #endregion


        private string GenerateOrderNo()
        {
            int runningNo = generateNoProvider.GenerateNo(C_KEY_ORDER);
            string orderNo = string.Format("{0}{1}", DateTime.Now.ToString("ddMMyy", new CultureInfo("en-US")), runningNo.ToString("000000"));
            return orderNo;
        }

        private void releaseObject(object obj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                obj = null;
            }
            catch (Exception ex)
            {
                obj = null;
                MessageBox.Show("Unable to release the Object " + ex.ToString());
            }
            finally
            {
                GC.Collect();
            }
        }

        private void ExportToExcel(object parameter)
        {
            tbl_Order selected = (tbl_Order)parameter;
            var ProductSummaryList = productSummaryProvider.GetProductSummary(null, selected.OrderNo);
            var dt = ConvertToDatatable(ProductSummaryList);

            //ExportDataTableToExcel(dt, selected.RefOrderNo);

        }

        //public void ExportDataTableToExcel(DataTable dt, string refOrderNo)
        //{
        //    Microsoft.Win32.SaveFileDialog dialog = new Microsoft.Win32.SaveFileDialog();
        //    dialog.ValidateNames = true;
        //    dialog.OverwritePrompt = true;
        //    dialog.FileName = string.Format("PLANT - {0}", refOrderNo);
        //    dialog.Filter = "EXCEL Files (*.xls)|*.xlsx";
        //    bool? dialogresult = dialog.ShowDialog(Application.Current.MainWindow);
        //    if (dialogresult.HasValue && dialogresult.Value)
        //    {
        //        Excel.Application xlApp = null;
        //        Excel.Workbook xlWorkBook = null;
        //        Excel.Worksheet xlWorkSheet = null;
        //        Excel.Range xlRange = null;

        //        try
        //        {
        //            xlApp = new Excel.Application();
        //            xlApp.Visible = false;

        //            xlWorkBook = xlApp.Workbooks.Add();
        //            xlWorkSheet = xlWorkBook.ActiveSheet;
        //            xlRange = xlWorkSheet.get_Range("A1", "Z500");

        //            //Header
        //            for (int i = 0; i < dt.Columns.Count; i++)
        //            {
        //                xlWorkSheet.Cells[1, i + 1] = dt.Columns[i].ColumnName;
        //                xlWorkSheet.Cells[1, i + 1].Style.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
        //            }

        //            // Content.  
        //            for (int i = 0; i < dt.Rows.Count; i++)
        //            {
        //                for (int j = 0; j < dt.Columns.Count; j++)
        //                {
        //                    xlWorkSheet.Cells[i + 2, j + 1] = dt.Rows[i][j];
        //                }
        //            }

        //            xlRange.EntireColumn.AutoFit();

        //            xlWorkBook.SaveAs(dialog.FileName, Excel.XlFileFormat.xlWorkbookDefault, Missing.Value,
        //                Missing.Value, false, false, Excel.XlSaveAsAccessMode.xlNoChange,
        //                Excel.XlSaveConflictResolution.xlUserResolution, true,
        //                Missing.Value, Missing.Value, Missing.Value);

        //            MessageBox.Show("Upload successful.");
        //        }
        //        catch (Exception ex)
        //        {
        //            MessageBox.Show(ex.Message);
        //        }
        //        finally
        //        {
        //            xlWorkBook.Close(false, null, null);
        //            xlApp.Quit();

        //            releaseObject(xlWorkSheet);
        //            releaseObject(xlWorkBook);
        //            releaseObject(xlApp);
        //            RefreshGrid();
        //        }
        //    }
        //}

        public DataTable ConvertToDatatable<T>(IList<T> data)
        {
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
            DataTable table = new DataTable();
            for (int i = 0; i < props.Count; i++)
            {
                PropertyDescriptor prop = props[i];
                table.Columns.Add(prop.Name, prop.PropertyType);
            }

            object[] values = new object[props.Count];
            foreach (T item in data)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    values[i] = props[i].GetValue(item);
                }
                table.Rows.Add(values);
            }

            return table;
        }
    }
}
